package com.example.demo.Service.lmp;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.demo.Dto.AddressDto;
import com.example.demo.Dto.AddressUpdateDto;
import com.example.demo.Mapper.AddressMapper;
import com.example.demo.Service.AddressService;
import com.example.demo.Util.ThreadLocallUtil;
import com.example.demo.VO.AddressInfoVo;
import com.example.demo.po.Address;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

@Service
public class AddressServicelmp extends ServiceImpl<AddressMapper, Address> implements AddressService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    @Transactional
    public void add(AddressDto addressDto) {
        Address address = BeanUtil.copyProperties(addressDto, Address.class);
        address.setCreateTime(LocalDateTime.now());
        address.setUpdateTime(LocalDateTime.now());
        address.setUserId(ThreadLocallUtil.getUser().getUserId());
        if (save(address)) {
            throw new RuntimeException("地址添加失败");
        }
    }

    @Override
    public AddressInfoVo getAll(Long id) {
        Object o = redisTemplate.opsForValue().get("address:" + id);
        if (o != null) {
            AddressInfoVo bean = JSONUtil.toBean(o.toString(), AddressInfoVo.class);
            return bean;
        }
        Address byId = getById(id);
        AddressInfoVo addressInfoVo = BeanUtil.copyProperties(byId, AddressInfoVo.class);
        redisTemplate.opsForValue().set("address:" + id, JSONUtil.toJsonStr(byId), RandomUtil.randomInt());
        return addressInfoVo;
    }

    @Override
    @Transactional
    public void delect(Long id) {
        if (removeById(id)) {
            redisTemplate.opsForValue().getAndDelete("address:" + id);
            return;
        }
        throw new RuntimeException("删除失败，地址id为" + id);
    }
    @Override
    @Transactional
    public void updateAddress(AddressUpdateDto addressUpdateDto) {
        // 创建更新包装器
        LambdaUpdateWrapper<Address> updateWrapper = new LambdaUpdateWrapper<>();
        // 只更新非空字段
        if (addressUpdateDto.getStreetAddress() != null) {
            updateWrapper.set(Address::getStreetAddress, addressUpdateDto.getStreetAddress());
        }
        if (addressUpdateDto.getCity() != null) {
            updateWrapper.set(Address::getCity, addressUpdateDto.getCity());
        }
        if (addressUpdateDto.getProvince() != null) {
            updateWrapper.set(Address::getProvince, addressUpdateDto.getProvince());
        }
        if (addressUpdateDto.getCountry() != null) {
            updateWrapper.set(Address::getCountry, addressUpdateDto.getCountry());
        }
        if (addressUpdateDto.getZipCode() != null) {
            updateWrapper.set(Address::getZipCode, addressUpdateDto.getZipCode());
        }
        // 设置更新时间和用户ID
        updateWrapper.set(Address::getUpdateTime, LocalDateTime.now())
                .eq(Address::getId, addressUpdateDto.getId())
                .eq(Address::getUserId, ThreadLocallUtil.getUser().getUserId());
        // 执行更新
        if (!update(updateWrapper)) {
            throw new RuntimeException("地址更新失败");
        }
        redisTemplate.delete("address:" + addressUpdateDto.getId());
    }
    @Override
    public IPage<AddressInfoVo> getAlladdresses(Integer pageSize, Integer pageNum) {
        if (pageNum == null || pageNum < 1){
            pageNum = 1;
            pageSize = 10;
        }
        Page<Address> updateTime = Page.of(pageNum, pageSize);
        Page<Address> page = lambdaQuery().eq(Address::getUserId, ThreadLocallUtil.getUser().getUserId()).page(updateTime);
        IPage<AddressInfoVo> addressInfoVoIPage = new Page<AddressInfoVo>().setSize(page.getSize()).
                setRecords(page.getRecords().stream().map(address -> BeanUtil.copyProperties(address, AddressInfoVo.class)).
                toList()).
                setTotal(page.getTotal()).
                setCurrent(page.getCurrent()).
                setPages(page.getPages());
        return addressInfoVoIPage;
    }
}
